/*
 * Copyright 2025 The JA-SIG Collaborative. All rights reserved.
 * distributed with this file and available online at
 */
package com.lap.auth.application.module;

import com.lap.auth.application.module.assembler.ModuleAssembler;
import com.lap.auth.application.module.command.CreateModuleCmd;
import com.lap.auth.application.module.command.UpdateModuleCmd;
import com.lap.auth.application.module.dto.ModuleDto;
import com.lap.auth.application.module.dto.QueryModulePageQuery;
import com.lap.auth.application.module.repository.ModuleQueryRepository;
import com.lap.auth.domain.api.repository.ApiRepository;
import com.lap.auth.domain.module.Module;
import com.lap.auth.domain.module.repository.ModuleRepository;
import com.lap.auth.domain.module.service.ModuleValidator;
import com.lap.framework.common.dto.page.PageResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 项目应用服务层
 *
 * <ol>
 *   <li>不做业务规则，只做技术规则（加密/解密是技术实现，业务不关注）
 *   <li>取数，赋值，对象转换在这层执行
 *   <li>命名有规范，动词+领域名字
 *   <li>如查询比较多，建议分开领域QueryAppService,如:分页查询，分页查询返回关联字段
 * </ol>
 */
@RequiredArgsConstructor
@Service
public class ModuleAppService {

  private final ModuleAssembler moduleAssembler;
  private final ModuleValidator moduleValidator;
  private final ModuleRepository repository;
  private final ApiRepository apiRepository;
  private final ModuleQueryRepository queryRepository;

  public PageResponse<ModuleDto> queryModulesByPage(QueryModulePageQuery query) {
    return queryRepository.findByConditionPaged(query);
  }

  public Integer createModule(CreateModuleCmd cmd) {
    moduleValidator.validateRouteIdUnique(cmd.getRouteId());
    Module module = moduleAssembler.toDomain(cmd);
    return repository.save(module);
  }

  public Integer updateModule(Integer id, UpdateModuleCmd cmd) {
    Module old = moduleValidator.assertModuleExists(id);
    Module module = moduleAssembler.toDomain(id, old.getRouteId(), cmd);
    return repository.save(module);
  }

  @Transactional(rollbackFor = Exception.class)
  public Integer deleteModule(Integer id) {
    Module module = moduleValidator.assertModuleExists(id);
    apiRepository.deleteByModule(module.getRouteId());
    return repository.deleteById(id);
  }
}
